package com.yosaa.back.service.impl;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.yosaa.back.entity.FitnessRecord;
import com.yosaa.back.entity.ScoringStandard;
import com.yosaa.back.entity.UserInfo;
import com.yosaa.back.entity.vo.KafkaData;
import com.yosaa.back.entity.vo.MoonshotResponse;
import com.yosaa.back.enums.*;
import com.yosaa.back.mapper.ScoringStandardMapper;
import com.yosaa.back.service.IFitnessRecordService;
import com.yosaa.back.service.IScoringStandardService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yosaa.back.service.IUsersService;
import com.yosaa.back.utils.TimeUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.*;
import org.springframework.kafka.support.Acknowledgment;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 体测评分标准表，存储不同体测项目的评分标准 服务实现类
 * </p>
 */
@Service
public class ScoringStandardServiceImpl extends ServiceImpl<ScoringStandardMapper, ScoringStandard> implements IScoringStandardService {
    @Autowired
    private IFitnessRecordService fitnessRecordService;
    @Autowired
    private IUsersService userService;

    private Float height = 0F;
    private Float weight = 0F;

    @Override
    public void processDataFromKafka(KafkaData task, Acknowledgment ack) {

        UserInfo user = userService.getById(task.getUserId());

        QueryWrapper<ScoringStandard> wrapper = new QueryWrapper<>();
        wrapper.eq("user_id", task.getUserId());

        ScoringStandard scoringStandard = getOne(wrapper);

        if (scoringStandard == null) {
            ScoringStandard info = new ScoringStandard();
            info.setUserId(task.getUserId());
            save(info);
        }


        task.getScores().forEach(scoreEntry -> {
            FitnessRecord fitnessRecord = new FitnessRecord();
            fitnessRecord.setUserId(task.getUserId());
            fitnessRecord.setProjectId(scoreEntry.getProject());
            fitnessRecord.setTestDate( TimeUtils.getCurrentTime());
            fitnessRecord.setScore(formatScore(scoreEntry.getProject(), scoreEntry.getScore()));
            fitnessRecordService.save(fitnessRecord);

            calScore(task.getUserId(), scoreEntry, user.getGrade(), user.getSex());
        });

        ScoringStandard newScoringStandard = getOne(wrapper);



        if(weight > 0 && height > 0){
            float bmi = (weight / (height * height));
            bmi = Float.parseFloat(String.format("%.2f", bmi));
            newScoringStandard.setScore6(bmi);
            weight = 0F;
            height = 0F;
        }
        try {
            Float totalScore = newScoringStandard.getScore1() * 0.1F + newScoringStandard.getScore2() * 0.2F  + newScoringStandard.getScore3() * 0.1F  + newScoringStandard.getScore4() * 0.2F  + newScoringStandard.getScore5() * 0.1F  + newScoringStandard.getScore6() * 0.15F + newScoringStandard.getScore7() * 0.15F;
            totalScore = Float.parseFloat(String.format("%.2f", totalScore));
            newScoringStandard.setScore(totalScore );
            newScoringStandard.setGrade(getGrade(totalScore));
            updateById(newScoringStandard);
        }catch (Exception e){
            e.printStackTrace();
        }

        ack.acknowledge();
    }


    public String getGrade(Float totalScore) {
        if (totalScore >= 90) {
            return "优秀";
        } else if (totalScore >= 80.0 && totalScore <= 89.9) {
            return "良好";
        } else if (totalScore >= 60.0 && totalScore <= 79.9) {
            return "及格";
        } else {
            return "不及格";
        }
    }
    private String formatScore(Integer id, String score) {
        String scoreStr = "";
        switch (id) {
            case 1:
                scoreStr = score + "  厘米";
                break;
            case 2:
                String[] str = score.split(":");
                if (str.length == 2){
                    scoreStr += str[0] + " 分" + str[1] + " 秒";
                }else if (str.length == 1){
                    scoreStr += str[0] + " 秒";
                }
                break;
            case 3:
                scoreStr = score + "  次";
                break;
            case 4:
                String[] str2 = score.split(":");
                if (str2.length == 2){
                    scoreStr += str2[0] + " 分" + str2[1] + " 秒";
                }else if (str2.length == 1){
                    scoreStr += str2[0] + " 秒";
                }
                break;
            case 5:
                scoreStr = score +  "  厘米";
                break;
            case 6:

                float score2 = Float.parseFloat(score);
                score2 = score2 > 5 ? score2 / 100 : score2;
                scoreStr = score2 +  "  米";
                break;
            case 7:
                scoreStr = score +  "  千克";
                break;
            case 8:
                scoreStr = score +  "  毫升";
                break;
            default:
                scoreStr = "错误数据";
                break;
        }
        return scoreStr;
    }

    private void calScore(Integer userId, KafkaData.ScoreEntry scoreEntry, String grade, String sex) {
        QueryWrapper<ScoringStandard> wrapper = new QueryWrapper<>();
        wrapper.eq("user_id", userId);

        ScoringStandard scoringStandard = getOne(wrapper);

        int projectId = scoreEntry.getProject();
        String scoreValue = scoreEntry.getScore();

        switch (projectId) {
            case 1: // 立定跳远
                if ("男".equals(sex)) {
                    scoringStandard.setScore1(MaleJumpScore.calculateScore(Integer.parseInt(scoreValue), grade));
                } else {
                    scoringStandard.setScore1(FemaleJumpScore.calculateScore(Integer.parseInt(scoreValue), grade));
                }
                break;
            case 2: //耐力跑
                if ("男".equals(sex)) {
                    float timeInSeconds = TimeUtils.convertToSeconds(scoreValue);
                    scoringStandard.setScore2(MaleEnduranceRunScore.calculateScore(timeInSeconds, grade));
                } else {
                    float timeInSeconds = TimeUtils.convertToSeconds(scoreValue);
                    scoringStandard.setScore2(FemaleEnduranceRunScore.calculateScore(timeInSeconds, grade));
                }
                break;
            case 3: //  引体向上（男）/1 分钟仰卧起坐（女）
                if ("男".equals(sex)) {
                    scoringStandard.setScore3(MalePullUpScore.calculateScore(Integer.parseInt(scoreValue), grade));
                } else {
                    scoringStandard.setScore3(FemaleSitUpScore.calculateScore(Integer.parseInt(scoreValue), grade));
                }
                break;
            case 4: //50米跑
                if ("男".equals(sex)) {
                    scoringStandard.setScore4(Male50mScore.calculateScore(Float.parseFloat(scoreValue), grade));
                } else {
                    scoringStandard.setScore4(Female50mScore.calculateScore(Float.parseFloat(scoreValue), grade));
                }
                break;
            case 5: // 坐位体前屈
                if ("男".equals(sex)) {
                    scoringStandard.setScore5(MaleSitReachScore.calculateScore(Float.parseFloat(scoreValue), grade));
                } else {
                    scoringStandard.setScore5(FemaleSitReachScore.calculateScore(Float.parseFloat(scoreValue), grade));
                }
                break;
            case 6:
                if (scoreValue == null || scoreValue.trim().isEmpty()) {
                    throw new IllegalArgumentException("输入的字符串为空或无效");
                }
                float score2 = Float.parseFloat(scoreValue);
                score2 = score2 > 5 ? score2 / 100 : score2;
                height += score2;
                break;
            case 7:
                weight += Float.parseFloat(scoreValue);
                break;
            case 8:
                scoringStandard.setScore7(MaleLungCapacityScore.calculateScore(Float.parseFloat(scoreValue), grade));
                scoringStandard.setScore7(FemaleLungCapacityScore.calculateScore(Float.parseFloat(scoreValue), grade));
                break;
            default:
                scoringStandard.setScore(0.0F); // 默认分数
                break;
        }

        updateById(scoringStandard);
    }

}
